﻿using System.Web;
using System.Web.Mvc;
using RenterClient.Service;
using RenterClient.Interfaces;
using System.Net.Http;
using System.Collections.Generic;
using RenterClient.Models;
using WebMatrix.WebData;
using System.Threading.Tasks;
using System;
using System.Net;

namespace RenterClient.Controllers
{

    public class AccountController : Controller
    {

        IRenterService _service = new RenterService();
        private LoginModel loginModel = null;

        public async void GetAuthentication(string username, string password)
        {
            HttpResponseMessage auth = await _service.Authentication(username, password);

            if (auth.IsSuccessStatusCode)
            {
                string connectId = string.Empty;
                IEnumerable<string> authenticationValues = auth.Headers.GetValues("Set-Cookie");
                foreach (string it in authenticationValues)
                {
                    string[] connectIdValue = it.Split(';');
                    connectId = connectIdValue[0].Substring(12);
                }

                HttpCookie cookie = cookie = new HttpCookie("connect.sid");
                cookie.Value = connectId;

                this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
            }
        }

        public ActionResult Login()
        {
            //ViewBag.ReturnUrl = returnUrl;
            loginModel = new LoginModel();
            return View(loginModel);
        }

        [HttpPost]
        public async Task<ActionResult> Login(LoginModel model, string returnUrl)
        {
            HttpResponseMessage auth = await _service.Authentication(model.UserName, model.Password);

            if (auth.IsSuccessStatusCode)
            {
                string connectId = string.Empty;
                IEnumerable<string> authenticationValues = auth.Headers.GetValues("Set-Cookie");
                foreach (string it in authenticationValues)
                {
                    string[] connectIdValue = it.Split(';');
                    connectId = connectIdValue[0].Substring(12);
                }

                HttpCookie cookie = cookie = new HttpCookie("connect.sid");
                cookie.Value = connectId;

                this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);

                return RedirectToAction("Index", "Home");
            }
            else if (auth.StatusCode == HttpStatusCode.Unauthorized)
            {
                loginModel = new LoginModel();
                loginModel.IsBadLoginPassword = true;
            }

            return View(loginModel);
        }

        public ActionResult LogOff()
        {
            HttpCookie cookie = cookie = Request.Cookies["connect.sid"];
            if (cookie != null)
            {
                cookie.Expires = DateTime.Now.AddDays(-1d);
                this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
            }

            return RedirectToAction("Index", "Home");
        }

        public ActionResult Register()
        {
            return View();
        }
    }


    //[Authorize]
    //[InitializeSimpleMembership]
    //public class AccountController : Controller
    //{
    //    //
    //    // GET: /Account/Login
    //    [AllowAnonymous]
    //    public ActionResult Login(string returnUrl)
    //    {
    //        ViewBag.ReturnUrl = returnUrl;
    //        return View();
    //    }

    //    //
    //    // POST: /Account/Login
    //    [HttpPost]
    //    [AllowAnonymous]
    //    [ValidateAntiForgeryToken]
    //    public ActionResult Login(LoginModel model, string returnUrl)
    //    {
    //        if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
    //        {
    //            return RedirectToLocal(returnUrl);
    //        }

    //        // If we got this far, something failed, redisplay form
    //        ModelState.AddModelError("", "The user name or password provided is incorrect.");
    //        return View(model);
    //    }

    //    //
    //    // POST: /Account/LogOff
    //    [HttpPost]
    //    [ValidateAntiForgeryToken]
    //    public ActionResult LogOff()
    //    {
    //        WebSecurity.Logout();

    //        return RedirectToAction("Index", "Home");
    //    }

    //    //
    //    // GET: /Account/Register
    //    [AllowAnonymous]
    //    public ActionResult Register()
    //    {
    //        return View();
    //    }

    //    //
    //    // POST: /Account/Register
    //    [HttpPost]
    //    [AllowAnonymous]
    //    [ValidateAntiForgeryToken]
    //    public ActionResult Register(RegisterModel model)
    //    {
    //        if (ModelState.IsValid)
    //        {
    //            // Attempt to register the user
    //            try
    //            {
    //                WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
    //                WebSecurity.Login(model.UserName, model.Password);
    //                return RedirectToAction("Index", "Home");
    //            }
    //            catch (MembershipCreateUserException e)
    //            {
    //                ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
    //            }
    //        }

    //        // If we got this far, something failed, redisplay form
    //        return View(model);
    //    }

    //    //
    //    // POST: /Account/Disassociate
    //    [HttpPost]
    //    [ValidateAntiForgeryToken]
    //    public ActionResult Disassociate(string provider, string providerUserId)
    //    {
    //        string ownerAccount = OAuthWebSecurity.GetUserName(provider, providerUserId);
    //        ManageMessageId? message = null;

    //        // Only disassociate the account if the currently logged in user is the owner
    //        if (ownerAccount == User.Identity.Name)
    //        {
    //            // Use a transaction to prevent the user from deleting their last login credential
    //            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Serializable }))
    //            {
    //                bool hasLocalAccount = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
    //                if (hasLocalAccount || OAuthWebSecurity.GetAccountsFromUserName(User.Identity.Name).Count > 1)
    //                {
    //                    OAuthWebSecurity.DeleteAccount(provider, providerUserId);
    //                    scope.Complete();
    //                    message = ManageMessageId.RemoveLoginSuccess;
    //                }
    //            }
    //        }

    //        return RedirectToAction("Manage", new { Message = message });
    //    }

    //    //
    //    // GET: /Account/Manage
    //    public ActionResult Manage(ManageMessageId? message)
    //    {
    //        ViewBag.StatusMessage =
    //            message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
    //            : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
    //            : message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
    //            : "";
    //        ViewBag.HasLocalPassword = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
    //        ViewBag.ReturnUrl = Url.Action("Manage");
    //        return View();
    //    }

    //    //
    //    // POST: /Account/Manage
    //    [HttpPost]
    //    [ValidateAntiForgeryToken]
    //    public ActionResult Manage(LocalPasswordModel model)
    //    {
    //        bool hasLocalAccount = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
    //        ViewBag.HasLocalPassword = hasLocalAccount;
    //        ViewBag.ReturnUrl = Url.Action("Manage");
    //        if (hasLocalAccount)
    //        {
    //            if (ModelState.IsValid)
    //            {
    //                // ChangePassword will throw an exception rather than return false in certain failure scenarios.
    //                bool changePasswordSucceeded;
    //                try
    //                {
    //                    changePasswordSucceeded = WebSecurity.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword);
    //                }
    //                catch (Exception)
    //                {
    //                    changePasswordSucceeded = false;
    //                }

    //                if (changePasswordSucceeded)
    //                {
    //                    return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
    //                }
    //                else
    //                {
    //                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
    //                }
    //            }
    //        }
    //        else
    //        {
    //            // User does not have a local password so remove any validation errors caused by a missing
    //            // OldPassword field
    //            ModelState state = ModelState["OldPassword"];
    //            if (state != null)
    //            {
    //                state.Errors.Clear();
    //            }

    //            if (ModelState.IsValid)
    //            {
    //                try
    //                {
    //                    WebSecurity.CreateAccount(User.Identity.Name, model.NewPassword);
    //                    return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
    //                }
    //                catch (Exception)
    //                {
    //                    ModelState.AddModelError("", String.Format("Unable to create local account. An account with the name \"{0}\" may already exist.", User.Identity.Name));
    //                }
    //            }
    //        }

    //        // If we got this far, something failed, redisplay form
    //        return View(model);
    //    }

    //    //
    //    // POST: /Account/ExternalLogin
    //    [HttpPost]
    //    [AllowAnonymous]
    //    [ValidateAntiForgeryToken]
    //    public ActionResult ExternalLogin(string provider, string returnUrl)
    //    {
    //        return new ExternalLoginResult(provider, Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
    //    }

    //    //
    //    // GET: /Account/ExternalLoginCallback
    //    [AllowAnonymous]
    //    public ActionResult ExternalLoginCallback(string returnUrl)
    //    {
    //        AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
    //        if (!result.IsSuccessful)
    //        {
    //            return RedirectToAction("ExternalLoginFailure");
    //        }

    //        if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
    //        {
    //            return RedirectToLocal(returnUrl);
    //        }

    //        if (User.Identity.IsAuthenticated)
    //        {
    //            // If the current user is logged in add the new account
    //            OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);
    //            return RedirectToLocal(returnUrl);
    //        }
    //        else
    //        {
    //            // User is new, ask for their desired membership name
    //            string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
    //            ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
    //            ViewBag.ReturnUrl = returnUrl;
    //            return View("ExternalLoginConfirmation", new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData });
    //        }
    //    }

    //    //
    //    // POST: /Account/ExternalLoginConfirmation
    //    [HttpPost]
    //    [AllowAnonymous]
    //    [ValidateAntiForgeryToken]
    //    public ActionResult ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl)
    //    {
    //        string provider = null;
    //        string providerUserId = null;

    //        if (User.Identity.IsAuthenticated || !OAuthWebSecurity.TryDeserializeProviderUserId(model.ExternalLoginData, out provider, out providerUserId))
    //        {
    //            return RedirectToAction("Manage");
    //        }

    //        if (ModelState.IsValid)
    //        {
    //            // Insert a new user into the database
    //            using (UsersContext db = new UsersContext())
    //            {
    //                UserProfile user = db.UserProfiles.FirstOrDefault(u => u.UserName.ToLower() == model.UserName.ToLower());
    //                // Check if user already exists
    //                if (user == null)
    //                {
    //                    // Insert name into the profile table
    //                    db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
    //                    db.SaveChanges();

    //                    OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
    //                    OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);

    //                    return RedirectToLocal(returnUrl);
    //                }
    //                else
    //                {
    //                    ModelState.AddModelError("UserName", "User name already exists. Please enter a different user name.");
    //                }
    //            }
    //        }

    //        ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(provider).DisplayName;
    //        ViewBag.ReturnUrl = returnUrl;
    //        return View(model);
    //    }

    //    //
    //    // GET: /Account/ExternalLoginFailure
    //    [AllowAnonymous]
    //    public ActionResult ExternalLoginFailure()
    //    {
    //        return View();
    //    }

    //    [AllowAnonymous]
    //    [ChildActionOnly]
    //    public ActionResult ExternalLoginsList(string returnUrl)
    //    {
    //        ViewBag.ReturnUrl = returnUrl;
    //        return PartialView("_ExternalLoginsListPartial", OAuthWebSecurity.RegisteredClientData);
    //    }

    //    [ChildActionOnly]
    //    public ActionResult RemoveExternalLogins()
    //    {
    //        ICollection<OAuthAccount> accounts = OAuthWebSecurity.GetAccountsFromUserName(User.Identity.Name);
    //        List<ExternalLogin> externalLogins = new List<ExternalLogin>();
    //        foreach (OAuthAccount account in accounts)
    //        {
    //            AuthenticationClientData clientData = OAuthWebSecurity.GetOAuthClientData(account.Provider);

    //            externalLogins.Add(new ExternalLogin
    //            {
    //                Provider = account.Provider,
    //                ProviderDisplayName = clientData.DisplayName,
    //                ProviderUserId = account.ProviderUserId,
    //            });
    //        }

    //        ViewBag.ShowRemoveButton = externalLogins.Count > 1 || OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
    //        return PartialView("_RemoveExternalLoginsPartial", externalLogins);
    //    }

    //    #region Helpers
    //    private ActionResult RedirectToLocal(string returnUrl)
    //    {
    //        if (Url.IsLocalUrl(returnUrl))
    //        {
    //            return Redirect(returnUrl);
    //        }
    //        else
    //        {
    //            return RedirectToAction("Index", "Home");
    //        }
    //    }

    //    public enum ManageMessageId
    //    {
    //        ChangePasswordSuccess,
    //        SetPasswordSuccess,
    //        RemoveLoginSuccess,
    //    }

    //    internal class ExternalLoginResult : ActionResult
    //    {
    //        public ExternalLoginResult(string provider, string returnUrl)
    //        {
    //            Provider = provider;
    //            ReturnUrl = returnUrl;
    //        }

    //        public string Provider { get; private set; }
    //        public string ReturnUrl { get; private set; }

    //        public override void ExecuteResult(ControllerContext context)
    //        {
    //            OAuthWebSecurity.RequestAuthentication(Provider, ReturnUrl);
    //        }
    //    }

    //    private static string ErrorCodeToString(MembershipCreateStatus createStatus)
    //    {
    //        // See http://go.microsoft.com/fwlink/?LinkID=177550 for
    //        // a full list of status codes.
    //        switch (createStatus)
    //        {
    //            case MembershipCreateStatus.DuplicateUserName:
    //                return "User name already exists. Please enter a different user name.";

    //            case MembershipCreateStatus.DuplicateEmail:
    //                return "A user name for that e-mail address already exists. Please enter a different e-mail address.";

    //            case MembershipCreateStatus.InvalidPassword:
    //                return "The password provided is invalid. Please enter a valid password value.";

    //            case MembershipCreateStatus.InvalidEmail:
    //                return "The e-mail address provided is invalid. Please check the value and try again.";

    //            case MembershipCreateStatus.InvalidAnswer:
    //                return "The password retrieval answer provided is invalid. Please check the value and try again.";

    //            case MembershipCreateStatus.InvalidQuestion:
    //                return "The password retrieval question provided is invalid. Please check the value and try again.";

    //            case MembershipCreateStatus.InvalidUserName:
    //                return "The user name provided is invalid. Please check the value and try again.";

    //            case MembershipCreateStatus.ProviderError:
    //                return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

    //            case MembershipCreateStatus.UserRejected:
    //                return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

    //            default:
    //                return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
    //        }
    //    }
    //    #endregion
    //}
}
